﻿@{
    ViewData["Title"] = "Home Page";
}
<script src="https://cdn.jsdelivr.net/npm/busy-load/dist/app.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/busy-load/dist/app.min.css" rel="stylesheet">
<script src="~/lib/fcup2/src/fcup.js"></script>
<script src="~/lib/tinymce/tinymce.min.js"></script>
<div class="text-center">
    <h1 class="display-4">大文件上传页面演示（For Asp.net Core）</h1>
    <br />
    <p>
        <button type="button" class="btn btn-primary" id="upid">上传</button>
    </p>
    
    <div class="progress">
        <div id="upload_progress" class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" style="width: 0%;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">0%</div>
    </div>
    <p id="result">
        <a id="file_url" target="_blank"></a><br />
        <button type="button" class="btn btn-outline-primary" id="btn_convert">转换文档</button><br />
        <a id="file_convert_url" target="_blank"></a>
    </p>
    <br />
</div>

<div class="alert alert-warning" role="alert">
    由于分段上传需要验证文件md5值，所以大文件上传前的等待时长可能会较长（1GB的文件大约需要30秒前置等待时间，可展示一个活动的loading框）
</div>
<div class="alert alert-info" role="alert">
    1.增加一个转换文档的功能，提供word和excel转pdf的功能，先上传文件，上传完成后，如果是符合格式要求的文档，可以进行转换。<br />
    2.增加一个富文本编辑器，tinyMCE，可借助写好的文件上传接口，配置其图片和文件上传
</div>
<div class="alert alert-danger" role="alert">
    注意：测试站点，水管有限，内部测试的同事测试的时候悠着些，别传太多太大的文件！！有事儿，跟在下说一声昂~
</div>

<div class="jumbotron">
    <div id="mytextarea"></div>
    <br />
    <button type="button" class="btn btn-outline-primary" id="btn_get">获取内容</button>
    <button type="button" class="btn btn-outline-info" id="btn_get_txt">获取纯文本内容</button>
    <button type="button" class="btn btn-outline-warning" id="btn_set">插入内容</button>
</div>


<script>
    let file_path = '';
    let uploaded_file_index = 0;
    //上传案例
    let up = new fcup({

        id: "upid", // 绑定id

        url: "@Url.Action("UploadWeb", "File")" ,// url地址

        checkurl: "@Url.Action("CheckFile","File")", // 检查上传url地址

        //注意配置跨域以后，下方回调函数里有涉及到生成下载链接的地方要注意修改！！
        //url: "http://10.185.1.41:88/file/uploadweb" ,// 跨域url地址(这个是我本地发布的地址)

        //checkurl: "http://10.185.1.41:88/file/checkfile", // 检查上传url地址

        //type: "jpg,png,jpeg,gif,mp4,mpeg,zip,rar", // 限制上传类型，为空不限制
        type: "", // 限制上传类型，为空不限制

        shardsize: "0.5", // 每次分片大小，单位为M，默认1M

        minsize: '', // 最小文件上传M数，单位为M，默认为无

        maxsize: "2048", // 上传文件最大M数，单位为M，默认200M

        // headers: {"version": "fcup-v2.0"}, // 附加的文件头,默认为null, 请注意指定header头时将不能进行跨域操作

        //apped_data: {"convert":1}, //每次上传的附加数据
        timeout: 600000,
        // 定义错误信息
        errormsg: {
            1000: "未找到上传id",
            1001: "类型不允许上传",
            1002: "上传文件过小",
            1003: "上传文件过大",
            1004: "上传请求超时"
        },

        // 错误提示
        error: (msg) => {
            alert(msg);
        },

        // 初始化事件
        start: () => {
            console.log('上传已准备就绪');
            Progress(0);
            $("#file_url").html("").removeAttr("href");
            file_path = '';
        },

        // 等待上传事件，可以用来loading
        beforeSend: () => {
            console.log('等待请求中');
        },

        // 上传进度事件
        progress: (num, other) => {
            uploaded_file_index = num;
            Progress(num);
            console.log(num);
            console.log('上传进度' + num);
            console.log("上传类型" + other.type);
            console.log("已经上传" + other.current);
            console.log("剩余上传" + other.surplus);
            console.log("已用时间" + other.usetime);
            console.log("预计时间" + other.totaltime);
        },

        // 检查地址回调,用于判断文件是否存在,类型,当前上传的片数等操作
        checksuccess: (res) => {
            let data = res ? eval('(' + res + ')') : '';
            let status = data.code;
            let msg = data.message;

            // 错误提示
            if (status == -1) {
                //alert(msg);
                Toaster("error", msg);
                return false;
            }

            // 已经上传
            if (status == 2) {
                Progress(100, 0);
                Toaster("warning ", msg);
                $("#file_url").html(location.href + data.data.url).removeAttr("href").attr("href", location.href + data.data.url);
                file_path = data.data.url;
                return false;
            }

            // 如果提供了这个参数,那么将进行断点上传的准备
            if (data.data && data.data.file_index) {
                //alert("已上传大约" + data.data.percent + "%");
                Toaster("warning", "已上传大约" + data.data.percent + "%", "提示");
                Progress(data.data.percent);
                // 起始上传的切片要从1开始
                let file_index = data.data.file_index ? parseInt(data.data.file_index) : 1;
                // 设置上传切片的起始位置
                up.setshard(file_index);

            }
            // 如果接口没有错误，必须要返回true，才不会终止上传
            return true;
        },

        // 上传成功回调，回调会根据切片循环，要终止上传循环，必须要return false，成功的情况下要始终返回true;
        success: (res) => {
            let data = res ? eval('(' + res + ')') : '';
            let url = data.url + "?" + Math.random();
            let file_index = data.file_index ? parseInt(data.file_index) : url
            if (data.completed) {
                Progress(100, 0);
                Toaster("success", "上传完成")
                $("#file_url").html(location.href + url).removeAttr("href").attr("href", location.href + url);
                file_path = data.url;
            }

            // 如果接口没有错误，必须要返回true，才不会终止上传循环
            return true;
        }
    });
    //增加一个富文本编辑器的演示，tinymce，中文文档：http://tinymce.ax-z.cn/
    tinymce.init({
        selector: '#mytextarea',
        language: 'zh_CN',//注意大小写
        plugins: 'link image axupimgs autosave print preview imagetools searchreplace wordcount',
        toolbar: 'undo redo | styleselect | bold italic underline alignleft alignright aligncenter searchreplace wordcount| link image axupimgs |preview print',
        setup: function (editor) {
            editor.on('change', function () { editor.save(); });
        },
        images_upload_handler: function (blobInfo, succFun, failFun) {
            var xhr, formData;
            var file = blobInfo.blob();//转化为易于理解的file对象
            xhr = new XMLHttpRequest();
            xhr.withCredentials = false;
            xhr.open('POST', '@Url.Action("UploadApi","File")');
            xhr.onload = function () {
                var json;
                if (xhr.status != 200) {
                    failFun('HTTP Error: ' + xhr.status);
                    console.log('HTTP Error: ' + xhr.status);
                    return;
                }
                json = JSON.parse(xhr.responseText);
                //if (!json || typeof json.location != 'string') {
                if (!json) {
                    //failFun('Invalid JSON: ' + xhr.responseText);
                    console.log('Invalid JSON: ' + xhr.responseText);
                    return;
                }
                succFun(json.data.url);
                //console.log(json);
            };
            //console.log(file.size);
            if (file.size && file.size > 1024 * 1024 * 10) {
                Toaster("error", "文件大小不可高于10M", "错误");
            } else {
                formData = new FormData();
                formData.append('file', file, file.name);//此处与源文档不一样
                formData.append('md5', new Date().getTime());//都是小文件，md5就不算了，直接取时间戳
                formData.append('fileName', file.name);//
                formData.append('total', 1);//固定值1
                formData.append('index', 1);//和total保持一致
                formData.append('rewrite', 1);//永远保持重写
                xhr.send(formData);
            }
        },
        file_picker_callback: function (callback, value, meta) {
            //console.log(value);
            //console.log(meta);

            //文件分类
            var filetype = '.pdf, .txt, .zip, .rar, .7z, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .mp3, .mp4';
            //后端接收上传文件的地址
            var upurl = '@Url.Action("UploadApi","File")';
            //模拟出一个input用于添加本地文件
            var input = document.createElement('input');
            input.setAttribute('type', 'file');
            input.setAttribute('accept', filetype);
            input.click();
            input.onchange = function () {
                var file = this.files[0];
                var xhr, formData;
                console.log(file.name);
                xhr = new XMLHttpRequest();
                xhr.withCredentials = false;
                xhr.open('POST', upurl);
                xhr.onload = function () {
                    var json;
                    if (xhr.status != 200) {
                        console.log('HTTP Error: ' + xhr.status);
                        return;
                    }
                    json = JSON.parse(xhr.responseText);
                    if (!json ) {
                        console.log('Invalid JSON: ' + xhr.responseText);
                        return;
                    }
                    callback(json.data.url);
                };
                if (file.size && file.size > 1024 * 1024 * 20) {
                    Toaster("error", "文件大小不可高于20M", "错误");
                } else {
                    formData = new FormData();
                    formData.append('file', file, file.name);
                    formData.append('md5', new Date().getTime());//都是小文件，md5就不算了，直接取时间戳
                    formData.append('fileName', file.name);//
                    formData.append('total', 1);//固定值1
                    formData.append('index', 1);//和total保持一致
                    formData.append('rewrite', 1);//永远保持重写
                    xhr.send(formData);
                }
            };
        },
    });

    //获取富文本内容
    $("#btn_get").click(function () {
        var text = tinyMCE.activeEditor.getContent();
        alert(text);
        //Toaster("info", text);
    })
    //获取纯文本
    $("#btn_get_txt").click(function () {
        var activeEditor = tinyMCE.activeEditor;
        var editBody = activeEditor.getBody();
        activeEditor.selection.select(editBody);
        var text = activeEditor.selection.getContent({ 'format': 'text' });
        Toaster("success", text);
    })
    //插入富文本内容
    $("#btn_set").click(function () {
        tinyMCE.activeEditor.setContent(new Date() + "  自定义内容");
    })

    //进度变化
    function Progress(value,animated=1) {
        let progress = $("#upload_progress");
        let percent = value + "%";
        progress.removeClass("bg-success");
        progress.html(percent);
        progress.css("width", percent);
        progress.attr("aria-valuenow", percent);
        if (animated == 0) {
            progress.removeClass("progress-bar-animated")
        } else {
            progress.addClass("progress-bar-animated")
        }
        if (value == 100 && !progress.hasClass("bg-success")) {
            progress.addClass("bg-success");

        }

    }
    //弹窗
    function Toaster(type, message, title = "消息") {
        $.Toast(title, message, type, {
            stack: true,
            has_icon: true,
            has_close_btn: true,
            position_class: "toast-top-right",
            fullscreen: false,
            timeout: 3000,
            sticky: false,
            has_progress: false,
            rtl: false,
        });
    }
    //文档转换
    $("#btn_convert").click(function () {
        if ($("#file_url").html().indexOf("doc") != -1 || $("#file_url").html().indexOf("xls") != -1) {
            loading();
            $.getJSON("@Url.Action("Convert2Pdf","File")", { "path": file_path }, function (json) {
                $("#file_convert_url").removeAttr("href").html(location.href + json.data.url).attr("href", location.href + json.data.url);
                closeLoading();
            })
        } else {
            Toaster("error", "格式不正确，只可以转换word或者excel文件");
        }
    });

    //loading
    function loading(elem = '.text-center') {
        $(elem).busyLoad("show", {
            //background: "#000",
            spinner: "accordion",
            animation: "slide",
            text: "准备中，请稍后..."
        });
    }
    function closeLoading(elem ='.text-center') {
        $(elem).busyLoad("hide");
    }


</script>